package yui.bss.demo.controller;

import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;

import com.baomidou.mybatisplus.core.metadata.IPage;

import yui.bss.demo.utils.JsonUtils;
import yui.comn.hub.data.parser.HubDataToMapParser;
import yui.comn.hub.xml.parser.HubXmlCache;
import yui.comn.mybatisx.core.conditions.query.FindWrapper;
import yui.comn.mybatisx.extension.conditions.GenerateWrapper;
import yui.comn.mybatisx.extension.conditions.clauses.QueryClause;

/**
 * 控制器的基类，将公共方法写在这个类中
 * 
 * @author yui
 */

public abstract class BaseController {
    protected final Logger log = LoggerFactory.getLogger(getClass());
    
    @Value("${spring.controller.openHeader: true}")  //默认开启查询接口返回字段含义
    private boolean isOpenHeader = true;
    
    protected static final String QUERY = "QUERY";
    
    protected static final String GRID = "GRID";
    protected static final String LIST = "LIST";
    protected static final String INFO = "INFO";
    protected static final String EXPT = "EXPT";
    protected static final String IMPT = "IMPT";
    protected static final String IMPT_ERR = "IMPT_ERR";
    protected static final String DTL = "DTL";
    
    protected static final int EXPORT_MAX_ROW = 20000;
    
    protected static final int SUCCESS = 0;
    protected static final String SUCCESS_MSG = "成功";
    protected static final int FAILURE = 400;
    
    protected static final String ITEMS = "list";
    
    /********************************************结果解析*****************************************************/
    public Object build(Object obj) {
        if (obj instanceof IPage) {
            return buildPage((IPage<?>) obj);
        } else if (obj instanceof Collection) {
            return buildList((Collection<?>) obj);
        } else {
            return buildObj(obj);
        }
    }
    
    public Object build(Object obj, String gridName) {
        if (obj instanceof IPage) {
            return buildPage((IPage<?>) obj, gridName);
        } else if (obj instanceof Collection) {
            return buildList((Collection<?>) obj, gridName);
        } else {
            return buildObj(obj, gridName);
        }
    }
    
    public Object buildSuccess() {
        return buildSuccess(SUCCESS_MSG);
    }
    
    public Object buildSuccess(String msg) {
        return buildResult(SUCCESS, null, null, msg, null);
    }
    
    public Object buildFailure(String message) {
        return buildResult(FAILURE, null, null, message, null);
    }
    
    public Object buildFailure(int code, String message) {
        return buildResult(code, null, null, message, null);
    }
    
    protected Object buildObj(Object obj) {
        return buildResult(SUCCESS, obj, null, null, null);
    }
    
    public Object buildObj(Object obj, String gridName) {
        Map<String, Object> mapData = HubDataToMapParser.getInstance().toMapByObj(this.getClass(), gridName, obj);
        return buildResult(SUCCESS, mapData, null, null, gridName);
    }
    
    public Object buildList(Collection<?> list) {
        Map<String, Collection<?>> mapData = getMapData(list);
        return buildResult(SUCCESS, mapData, null, null, null);
    }
    
    public Object buildList(Collection<?> list, String gridName) {
        List<Map<String, Object>> mapList = HubDataToMapParser.getInstance().toMapListByObjList(this.getClass(), gridName, list);
        Map<String, Collection<?>> mapData = getMapData(mapList);
        return buildResult(SUCCESS, mapData, null, null, gridName);
    }
    
    public Object buildPage(IPage<?> page) {
        Map<String, Collection<?>> mapData = getMapData(page.getRecords());
        return buildResult(SUCCESS, mapData, page, null, null);
    }
    
    public Object buildPage(IPage<?> page, String gridName) {
        List<Map<String, Object>> list = HubDataToMapParser.getInstance().toMapListByObjList(this.getClass(), gridName, page.getRecords());
        Map<String, Collection<?>> mapData = getMapData(list);
        return buildResult(SUCCESS, mapData, page, null, gridName);
    }
    
    private Object buildResult(int code, Object data, IPage<?> page, String msg, String gridName) {
        Map<String, Object> root = new LinkedHashMap<String, Object>();
        root.put("code", code);
        if (null != msg) {
            root.put("msg", msg);
        }
        if (null != gridName && isOpenHeader) {
            root.put("header", HubXmlCache.getInstance().toGridKvMap(this.getClass(), gridName));
        }
        if (null != data) {
            root.put("data", data);
        }
        if (null != page) {
            Map<String, Object> pagination = new HashMap<String, Object>();
            pagination.put("total", page.getTotal());
            pagination.put("pageSize", page.getSize());
            pagination.put("pageNum", page.getCurrent());
            root.put("page", pagination);
        }
        return root;
    }
    
    private Map<String, Collection<?>> getMapData(Collection<?> list) {
        Map<String, Collection<?>> map = new HashMap<>();
        map.put(ITEMS, list);
        return map;
    }
    
    /********************************************设置参数*****************************************************/
    protected <V> FindWrapper<V> getWrapper(String query, Class<V> voClass) {
        return getWrapper(query, voClass, QUERY, LIST);
    }
    
    protected <V> FindWrapper<V> getWrapper(String query, Class<V> entityClass, 
            String queryMapperName, String selectMapperName) {
        // 判断查询条件是否为空
        if (StringUtils.isBlank(query)) {
            // 如果为空，则返回一个空的查询条件
            return new FindWrapper<>();
        }

        FindWrapper<V> wrapper = new FindWrapper<>();
        /**
         *  解析查询条件
         *   {
         *      "controller": "SysUserController",
         *      "grids": {
         *        "USER_ROLE": {
         *          "columns": [
         *            {
         *              "type": "yui.bss.demo.vo.SysUserVo",
         *              "prefix": null
         *            },
         *            {
         *              "type": "yui.bss.demo.vo.SysRoleVo",
         *              "prefix": "role"
         *            }
         *          ]
         *        }
         *      }
         *    }
         */

        Map<String, String> queryMapper = HubXmlCache.getInstance().toSearch(getClass(), queryMapperName);

        // 解析成一个对象
        QueryClause queryClause = JsonUtils.JsonStr2JavaBean(query, QueryClause.class);
        
        Map<String, String> fieldMapper = null;
        if (null != queryClause.getS()) {
            fieldMapper = HubXmlCache.getInstance().toGridFieldKvList(getClass(), selectMapperName);
        }
        
        GenerateWrapper.wrapperHandle(wrapper, queryClause, queryMapper, fieldMapper);
        
        return wrapper;
    }
    
}
